import re

ERRMESSAGE = 'Invalid regular expression.  Please try again'

def raw(string):
    '''To literally save one keystroke'''
    return repr(string)

def sanitizeHTML(*strings):
    
    retlist = []
    
    for string in strings:
        retstring = string
        retstring = retstring.replace('&', '&amp;')
        retstring = retstring.replace('<', '&lt;')
        retstring = retstring.replace('>', '&gt;')
        #Handle line breaks for HTML output:
        retstring = retstring.replace('\n', r'<br>')
        retlist.append(retstring)

    return tuple(retlist)

def preify(text):
    #return '<pre>' + sanitizeHTML(text)[0] + '</pre>'
    return '<pre>' + text + '</pre>'

def codify(text):
    #return '<code>' + sanitizeHTML(text)[0] + '</code>'
    return '<code>' + text + '</code>'

def matchText(matchpattern, texttomatch, flags = 0, count=0):
    #matchpattern, texttomatch = sanitizeHTML(matchpattern, texttomatch)
    texttomatch, = sanitizeHTML(texttomatch)
    
    resRE = r'<span class="match">\g<0></span>'
       
    try:
        matchRE = re.compile(matchpattern, flags)
        matchresult = re.sub(matchRE, resRE, texttomatch, count)
        matches = re.findall(matchRE, texttomatch)
        if count > 0:
            matches = matches[0:count]
        
        it = re.finditer(matchRE, texttomatch)
        
        groups = []
        groupdict = {}
        x = 0
        
        while True:
            try:
                matchObj = it.next()
                groups += matchObj.groups()
                groupdict.update(matchObj.groupdict())
                x += 1 # Adds one to x
                if x >= count and count > 0:
                    break
                
            except StopIteration:
                break
        
        
    except:
        matchresult = ERRMESSAGE 
        matches = None
        groups, groupdict = None, None
        return matchresult, matches, groups, groupdict


    
    #Nice output formatting
#    matchresult = codify(matchresult)
#    matches = [codify(match) for match in matches]
#    groups = [codify(group) for group in groups]
    
    
    return matchresult, matches, groups, groupdict

def replaceText(matchpattern, replpattern, texttomatch, flags = 0, count=0):
    #matchpattern, replpattern, texttomatch = sanitizeHTML(matchpattern, replpattern, texttomatch)
    replpattern, texttomatch = sanitizeHTML(replpattern, texttomatch)
    
    repRE = r'<span class="match">' + replpattern + r'</span>'
        
    #Handle line breaks for HTML input
    texttomatch = re.sub(r'<br>', r'\n', texttomatch)

    try:
        matchRE = re.compile(matchpattern, flags)
        represult, nsubs = re.subn(matchRE, repRE, texttomatch, count)
    except:
        represult = ERRMESSAGE 
        nsubs = None
        groups, groupdict = None, None
        return represult, nsubs, groups, groupdict
        
    it = re.finditer(matchpattern, texttomatch)
        
    groups = []
    groupdict = {}
    x = 0
        
    while True:
        try:
            matchObj = it.next()
            groups += matchObj.groups()
            groupdict.update(matchObj.groupdict())
            x += 1 # Adds one to x
            if x >= count and count > 0:
                break
                
        except StopIteration:
            break

    
    #Nice output formatting
#    represult = codify(represult)
#    groups = [codify(group) for group in groups]

    return represult, nsubs, groups, groupdict
    

def splitText(splitpattern, texttosplit, flags=0, count=0):
    
    #splitpattern, texttosplit = sanitizeHTML(splitpattern, texttosplit)
    
    texttosplit, = sanitizeHTML(texttosplit)
        
    #Handle line breaks for HTML input
    texttosplit = re.sub(r'<br>', r'\n', texttosplit)

    try:
        splitRE = re.compile(splitpattern, flags)
        splitgroups = re.split(splitRE, texttosplit, maxsplit=count)
    except:
        splitgroups = ERRMESSAGE
        groups, groupdict = None, None
        return splitgroups, groups, groupdict
        
    it = re.finditer(splitpattern, texttosplit)
        
    groups = []
    groupdict = {}
    x = 0
        
    while True:
        try:
            matchObj = it.next()
            groups += matchObj.groups()
            groupdict.update(matchObj.groupdict())
            x += 1 # Adds one to x
            if x >= count and count > 0:
                break
                
        except StopIteration:
            break

    #Nice output formatting
#    splitgroups = [codify(splitgroup) for splitgroup in splitgroups]
#    groups = [codify(group) for group in groups]

    return splitgroups, groups, groupdict

def regexReplacefunc(text, regexIN, groupnum, repfunc):
    '''Searches for patterns matching the regex in the text string, takes group groupnum out of the match and feeds it into the function repfunc.  Then replaces the entire regex with the result of repfunc.  Repfunc should take and return a string.'''
    while True:
        match = re.search(regexIN, text)
        
        if not match:
            break

        group = match.group(groupnum)
        wholeMatch = match.group(0)
        repstr = repfunc(group)

        text = text.replace(wholeMatch, repstr)

    return text




def main():
    print replaceText(r'a+', 'c', 'aaaaaaaaabbbbbbbaaaaaaa')[0]


if __name__ == '__main__':
    main()
